package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/catroll/fastdns/internal/api"
	"github.com/catroll/fastdns/internal/config"
	"github.com/catroll/fastdns/internal/dns"
	"github.com/catroll/fastdns/internal/logger"
)

var (
	configPath = flag.String("config", "config.yaml", "配置文件路径")
	version    = "1.0.0"
)

func main() {
	// 解析命令行参数
	flag.Parse()

	// 显示版本信息
	fmt.Printf("FastDNS 版本 %s\n", version)
	fmt.Printf("启动时间: %s\n", time.Now().Format("2006-01-02 15:04:05"))

	// 加载配置
	cfg, err := config.LoadConfig(*configPath)
	if err != nil {
		fmt.Printf("加载配置失败: %v\n", err)
		os.Exit(1)
	}

	// 初始化日志系统
	if err := logger.Setup(cfg); err != nil {
		fmt.Printf("初始化日志系统失败: %v\n", err)
		os.Exit(1)
	}

	logger.Info("FastDNS 启动中", "version", version, "config_path", *configPath)

	// 创建 DNS 解析器
	resolver, err := dns.NewResolver(cfg)
	if err != nil {
		logger.Error("创建 DNS 解析器失败", "error", err)
		os.Exit(1)
	}

	// 启动上游 DNS 服务器健康检查
	resolver.StartHealthCheck(30 * time.Second)

	// 创建共享的查询计数器
	var queryCount int64

	// 创建 API 服务器
	apiServer := api.NewServer(cfg, resolver, &queryCount)

	// 启动 API 服务器（在后台运行）
	go func() {
		if err := apiServer.Start(); err != nil {
			logger.Error("API 服务器启动失败", "error", err)
			os.Exit(1)
		}
	}()

	// 创建 DNS 服务器
	dnsServer := dns.NewServer(cfg, resolver)

	// 设置查询计数器
	dnsServer.SetQueryCounter(&queryCount)

	// 启动 DNS 服务器（在后台运行）
	go func() {
		if err := dnsServer.Start(); err != nil {
			logger.Error("DNS 服务器启动失败", "error", err)
			os.Exit(1)
		}
	}()

	// 等待终止信号
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh

	logger.Info("收到终止信号，正在关闭服务...")

	// 创建一个带超时的上下文用于优雅关闭
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// 关闭 DNS 服务器
	if err := dnsServer.Stop(ctx); err != nil {
		logger.Error("关闭 DNS 服务器失败", "error", err)
	}

	// 关闭 API 服务器
	if err := apiServer.Stop(ctx); err != nil {
		logger.Error("关闭 API 服务器失败", "error", err)
	}

	logger.Info("FastDNS 已关闭")
}
